#include <cstdlib>
#include "../Tools/GLHeaders.hpp"
#include "../Global.hpp"
#include "Terrain.hpp"

#if DEBUG
#include <cstdio>
#endif

Terrain::Terrain(void){
  InitTexture();
  InitTiles();
  RenderToTexture(1.0f, 1.0f, 1.0f, 1.0f);
}

Terrain::~Terrain(void){
  glDeleteBuffers(2, terrain_buffers);
  glDeleteTextures(1, &txt_id);
  glDeleteTextures(16, txt_tiles);
  delete[] terrain_buffers;
}

void Terrain::Draw(GLfloat r, GLfloat g, GLfloat b, GLfloat a){
  glPushAttrib(GL_COLOR_BUFFER_BIT|GL_TEXTURE_BIT);
  glColor4f(r, g, b, a);

  glBindTexture(GL_TEXTURE_2D, txt_id);
  glBegin(GL_QUADS);
  glNormal3f(0.0f ,0.0f ,1.0f);
  glTexCoord2f(0.0f, 0.0f);  glVertex3f(-1.0f,-1.0f, 1.0f);
  glTexCoord2f(1.0f, 0.0f);  glVertex3f( 1.0f,-1.0f, 1.0f);
  glTexCoord2f(1.0f, 1.0f);  glVertex3f( 1.0f, 1.0f, 1.0f);
  glTexCoord2f(0.0f, 1.0f);  glVertex3f(-1.0f, 1.0f, 1.0f);
  glEnd();

  glBindTexture(GL_TEXTURE_2D, txt_tiles[4]);
  glBegin(GL_QUADS);
  glNormal3f(0.0f ,0.0f ,-1.0f);
  glTexCoord2f(1.0f, 0.0f);  glVertex3f(-0.5f,-1.0f,-1.0f);
  glTexCoord2f(1.0f, 2.0f);  glVertex3f(-0.5f, 1.0f,-1.0f);
  glTexCoord2f(0.0f, 2.0f);  glVertex3f( 0.5f, 1.0f,-1.0f);
  glTexCoord2f(0.0f, 0.0f);  glVertex3f( 0.5f,-1.0f,-1.0f);
  glEnd();

  glPopAttrib();
}

void Terrain::InitTexture(void){
  txt_width = 2048;
  txt_height = 2048;

  glGenTextures(16, txt_tiles);
  glEnable(GL_TEXTURE_2D);
  for(int i=0; i < 16; i++){
    glBindTexture(GL_TEXTURE_2D, txt_tiles[i]);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, txt_width/4, txt_height/4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  }

    glGenTextures(1, &txt_id);
    glBindTexture(GL_TEXTURE_2D, txt_id);
	  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, txt_width, txt_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

  glGenRenderbuffersEXT(1, &rbo_id);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rbo_id);
  glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, txt_width, txt_height);
  glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
 
  glGenFramebuffersEXT(1, &fbo_id);
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);
  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, txt_id, 0);
  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo_id);

#if DEBUG
  if(GL_FRAMEBUFFER_COMPLETE_EXT != glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT))
    fprintf(stderr,"Terrain : FrameBuffer status fails\n");
#endif
   glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

void Terrain::InitTiles(void){
  GLfloat factor_width = (GLfloat)txt_width/(12.0f*4.0f);
  GLfloat factor_height = (GLfloat)txt_height/(12.0f*4.0f);

  GLfloat terrain_array[444] = {//NORMAL, VERTEX
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 0.0f*factor_height, 0.0f, // 0
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 0.0f*factor_height, 0.0f, // 1
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 0.0f*factor_height, 0.0f, // 2
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 0.0f*factor_height, 0.0f, // 3
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 1.0f*factor_height, 0.0f, // 4
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 1.0f*factor_height, 0.0f, // 5
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 1.0f*factor_height, 0.0f, // 6
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 1.0f*factor_height, 0.0f, // 7
    0.0f, 0.0f, 1.0f, 1.0f*factor_width, 2.0f*factor_height, 0.0f, // 8
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 2.0f*factor_height, 0.0f, // 9
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 2.0f*factor_height, 0.0f, // 10
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 2.0f*factor_height, 0.0f, // 11
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 2.0f*factor_height, 0.0f, // 12
    0.0f, 0.0f, 1.0f,11.0f*factor_width, 2.0f*factor_height, 0.0f, // 13
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 3.0f*factor_height, 0.0f, // 14
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 3.0f*factor_height, 0.0f, // 15
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 3.0f*factor_height, 0.0f, // 16
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 3.0f*factor_height, 0.0f, // 17
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 3.0f*factor_height, 0.0f, // 18
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 3.0f*factor_height, 0.0f, // 19
    0.0f, 0.0f, 1.0f, 1.0f*factor_width, 4.0f*factor_height, 0.0f, // 20
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 4.0f*factor_height, 0.0f, // 21
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 4.0f*factor_height, 0.0f, // 22
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 4.0f*factor_height, 0.0f, // 23
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 4.0f*factor_height, 0.0f, // 24
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 4.0f*factor_height, 0.0f, // 25
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 4.0f*factor_height, 0.0f, // 26
    0.0f, 0.0f, 1.0f,11.0f*factor_width, 4.0f*factor_height, 0.0f, // 27
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 5.0f*factor_height, 0.0f, // 28
    0.0f, 0.0f, 1.0f, 3.0f*factor_width, 5.0f*factor_height, 0.0f, // 29
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 5.0f*factor_height, 0.0f, // 30
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 5.0f*factor_height, 0.0f, // 31
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 5.0f*factor_height, 0.0f, // 32
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 5.0f*factor_height, 0.0f, // 33
    0.0f, 0.0f, 1.0f, 9.0f*factor_width, 5.0f*factor_height, 0.0f, // 34
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 5.0f*factor_height, 0.0f, // 35
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 6.0f*factor_height, 0.0f, // 36
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 6.0f*factor_height, 0.0f, // 37
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 7.0f*factor_height, 0.0f, // 38
    0.0f, 0.0f, 1.0f, 3.0f*factor_width, 7.0f*factor_height, 0.0f, // 39
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 7.0f*factor_height, 0.0f, // 40
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 7.0f*factor_height, 0.0f, // 41
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 7.0f*factor_height, 0.0f, // 42
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 7.0f*factor_height, 0.0f, // 43
    0.0f, 0.0f, 1.0f, 9.0f*factor_width, 7.0f*factor_height, 0.0f, // 44
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 7.0f*factor_height, 0.0f, // 45
    0.0f, 0.0f, 1.0f, 1.0f*factor_width, 8.0f*factor_height, 0.0f, // 46
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 8.0f*factor_height, 0.0f, // 47
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 8.0f*factor_height, 0.0f, // 48
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 8.0f*factor_height, 0.0f, // 49
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 8.0f*factor_height, 0.0f, // 50
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 8.0f*factor_height, 0.0f, // 51
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 8.0f*factor_height, 0.0f, // 52
    0.0f, 0.0f, 1.0f,11.0f*factor_width, 8.0f*factor_height, 0.0f, // 53
    0.0f, 0.0f, 1.0f, 2.0f*factor_width, 9.0f*factor_height, 0.0f, // 54
    0.0f, 0.0f, 1.0f, 4.0f*factor_width, 9.0f*factor_height, 0.0f, // 55
    0.0f, 0.0f, 1.0f, 5.0f*factor_width, 9.0f*factor_height, 0.0f, // 56
    0.0f, 0.0f, 1.0f, 7.0f*factor_width, 9.0f*factor_height, 0.0f, // 57
    0.0f, 0.0f, 1.0f, 8.0f*factor_width, 9.0f*factor_height, 0.0f, // 58
    0.0f, 0.0f, 1.0f,10.0f*factor_width, 9.0f*factor_height, 0.0f, // 59
    0.0f, 0.0f, 1.0f, 1.0f*factor_width,10.0f*factor_height, 0.0f, // 60
    0.0f, 0.0f, 1.0f, 4.0f*factor_width,10.0f*factor_height, 0.0f, // 61
    0.0f, 0.0f, 1.0f, 5.0f*factor_width,10.0f*factor_height, 0.0f, // 62
    0.0f, 0.0f, 1.0f, 7.0f*factor_width,10.0f*factor_height, 0.0f, // 63
    0.0f, 0.0f, 1.0f, 8.0f*factor_width,10.0f*factor_height, 0.0f, // 64
    0.0f, 0.0f, 1.0f,11.0f*factor_width,10.0f*factor_height, 0.0f, // 65
    0.0f, 0.0f, 1.0f, 2.0f*factor_width,11.0f*factor_height, 0.0f, // 66
    0.0f, 0.0f, 1.0f, 4.0f*factor_width,11.0f*factor_height, 0.0f, // 67
    0.0f, 0.0f, 1.0f, 8.0f*factor_width,11.0f*factor_height, 0.0f, // 68
    0.0f, 0.0f, 1.0f,10.0f*factor_width,11.0f*factor_height, 0.0f, // 69
    0.0f, 0.0f, 1.0f, 2.0f*factor_width,12.0f*factor_height, 0.0f, // 70
    0.0f, 0.0f, 1.0f, 4.0f*factor_width,12.0f*factor_height, 0.0f, // 71
    0.0f, 0.0f, 1.0f, 8.0f*factor_width,12.0f*factor_height, 0.0f, // 72
    0.0f, 0.0f, 1.0f,10.0f*factor_width,12.0f*factor_height, 0.0f  // 73
  };

  GLuint indices_array[354] = {
    // Left line (0)
    1,71,0,0,71,70,
    // Right line (6)
    3,73,2,2,73,72, 
    // Bottom left circle (12)
    1,5,0,0,5,4,
    4,5,10,4,10,8,
    8,10,23,8,23,20,
    20,23,30,20,30,28,
    // Bottom right circle (36)
    3,7,2,2,7,6,
    6,7,13,6,13,11,
    11,13,27,11,27,24,
    24,27,35,24,35,33,
    // Top left circle (60)
    40,49,38,38,49,46,
    46,49,62,46,62,60,
    60,62,67,60,67,66,
    66,67,71,66,71,70,
    // Top right circle (84)
    45,53,43,43,53,50,
    50,53,65,50,65,63,
    63,65,69,63,69,68,
    68,69,73,68,73,72,
    // Left line + bottom right (108)
    1,71,0,0,71,70,
    9,16,36,36,16,31,
    31,16,17,31,17,33,
    33,17,12,33,12,19,
    19,12,2,19,2,3,
    // Left line + top right (138)
    1,71,0,0,71,70,
    36,41,61,61,41,56,
    56,41,43,56,43,57,
    57,43,59,57,59,64,
    64,59,73,64,73,72,
    // Right line + bottom left (168)
    1,9,0,0,9,14,
    14,9,16,14,16,30,
    30,16,17,30,17,32,
    32,17,12,32,12,37,
    72,2,73,73,2,3,
    // Right line + top left (198)
    3,73,2,2,73,72,
    64,57,37,37,57,42,
    42,57,56,42,56,40,
    40,56,61,40,61,54,
    54,61,71,54,71,70,
    // Bottom line (228)
    1,9,0,0,9,21,
    21,9,16,21,16,29,
    29,16,17,29,17,34,
    34,17,12,34,12,26,
    26,12,2,26,2,3,
    // Top line (258)
    70,47,71,71,47,61,
    61,47,39,61,39,56,
    56,39,44,56,44,57,
    57,44,52,57,52,64,
    64,52,73,64,73,72,
    // Bottom left to Top right (288)
    1,15,0,0,15,21,
    21,15,52,21,52,58,
    58,52,73,58,73,72,
    // Bottom right to Top left (306)
    3,26,2,2,26,18,
    18,26,55,18,55,47,
    47,55,71,47,71,70,
    // Cross lines (324)
    1,71,0,0,71,70,
    22,31,48,48,31,41,
    41,31,33,41,33,42,
    42,33,25,42,25,51,
    72,2,73,73,2,3
  };

  terrain_buffers = (GLuint *) new GLuint[2];
  glGenBuffers(2, terrain_buffers);

  glBindBuffer(GL_ARRAY_BUFFER, terrain_buffers[0]);
  glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*444, terrain_array, GL_STATIC_DRAW);

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrain_buffers[1]);
  glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*354, indices_array, GL_STATIC_DRAW);
}

void Terrain::RenderToTexture(GLfloat r, GLfloat g, GLfloat b, GLfloat a){
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo_id);

  glPushAttrib(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_TEXTURE_BIT);
  glColor4f(r, g, b, a);
  glViewport(0, 0, txt_width, txt_height);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadIdentity();
  glOrtho(0, txt_width, 0, txt_height, -1.0f, 1.0f);
 
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadIdentity();

  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  DrawTiles();
  glBindTexture(GL_TEXTURE_2D, txt_id);
  glGenerateMipmapEXT(GL_TEXTURE_2D);

  GLubyte *data;
  data = (GLubyte *)malloc(sizeof(GLubyte)*txt_width/4*txt_height/4*4);

  for(int j=0; j < 4; j++){
    for(int i=0; i < 4; i++){
    glReadPixels(i*txt_width/4, j*txt_height/4, txt_width/4, txt_height/4, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D, txt_tiles[j*4+i]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, txt_width/4, txt_height/4, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    }
  }
  glBindTexture(GL_TEXTURE_2D, 0);
  free(data);
 
  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
  glViewport(0, 0, window.width, window.height);
  glMatrixMode( GL_PROJECTION );
  glPopMatrix();
  glMatrixMode( GL_MODELVIEW );
  glPopMatrix();
  glPopAttrib();
}

void Terrain::DrawTiles(void){
  glBindBuffer(GL_ARRAY_BUFFER, terrain_buffers[0]);
  glNormalPointer(GL_FLOAT, 6 * sizeof(GLfloat), 0);
  glVertexPointer(3, GL_FLOAT, 6 * sizeof(GLfloat), ((GLfloat*)NULL+(3)));

  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, terrain_buffers[1]);

  glEnableClientState(GL_NORMAL_ARRAY);
  glEnableClientState(GL_VERTEX_ARRAY);
 
  //  0 : LL LL
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(0)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(6))); 
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  1 : LL LL
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(0)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(6)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  2 : LL LL
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(0)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(6)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  3 : LL LL
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(0)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(6)));
  glTranslatef(-3*txt_width/4, txt_height/4, 0.0f);
  //  4 : BLc RL+TL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(12)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(198)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  5 : BRc LL+TR
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(36)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(138)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  6 : TLc RL+BL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(60)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(168)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  7 : TRc LL+BR
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(84)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(108)));
  glTranslatef(-3*txt_width/4, txt_height/4, 0.0f);
  //  8 : BLc BRc TL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(12)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(36)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(258)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  //  9 : TLc TRc BL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(60)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(84)));
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(228)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  // 10 : BLc TLc RL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(12)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(60)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(6)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  // 11 : BRc TRc LL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(36)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(84)));
  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, ((GLfloat*)NULL+(0)));
  glTranslatef(-3*txt_width/4, txt_height/4, 0.0f);
  // 12 : BLc TRc BR+TL
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(12)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(84)));
  glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, ((GLfloat*)NULL+(306)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  // 13 : BRc TLc BL+TR
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(36)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(60)));
  glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, ((GLfloat*)NULL+(288)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  // 14 : BLc BRc TLc TRc
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(12)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(36)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(60)));
  glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_INT, ((GLfloat*)NULL+(84)));
  glTranslatef(txt_width/4, 0.0f, 0.0f);
  // 15 : X
  glDrawElements(GL_TRIANGLES, 30, GL_UNSIGNED_INT, ((GLfloat*)NULL+(324)));
  glTranslatef(-3*txt_width/4, -3*txt_height/4, 0.0f);

  glDisableClientState(GL_NORMAL_ARRAY);
  glDisableClientState(GL_VERTEX_ARRAY);
}
